home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / dev.c.metrum < prev    next >
Encoding:
Text File  |  1992-10-26  |  13.5 KB  |  680 lines

  1. /* 
  2.  * dev.c--
  3.  *
  4.  *    Device-dependent manipulations for Metrum RSS-600
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "What a depressingly stupid machine"
  17.  *      -- Marvin in _A Hitchiker's Guide to the Galaxy_
  18.  *
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/dev.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <sys/mtio.h>
  28. #include "jaquith.h"
  29. #include "asaca.h"
  30.  
  31. typedef struct mtop Dev_TapeCommand;
  32.  
  33. static char printBuf[T_MAXSTRINGLEN];
  34. extern int syserr;
  35.  
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * Dev_MoveVolume --
  41.  *
  42.  *    Move a volume from source slot to destination slot in jukebox
  43.  *
  44.  * Results:
  45.  *    Ptr to block of specified size or NULL;
  46.  *
  47.  * Side effects:
  48.  *    Moves robot arm. May also affect volume reader.
  49.  *
  50.  * Note:
  51.  *      The tape reader devices in the Metrum RSS-600 jukebox are given slot
  52.  *      numbers 604-609. If one of these is the destination address
  53.  *      a tape load is effectively done.  
  54.  *
  55.  *----------------------------------------------------------------------
  56.  */
  57.  
  58. int
  59. Dev_MoveVolume(robotStream, src, dest)
  60.     int robotStream;          /* robot file descriptor */
  61.     int src;                  /* source location */
  62.     int dest;                 /* destination location */
  63. {
  64.     struct ascmd asacaCmd;
  65.  
  66.     int cmdType;
  67.     asacaCmd.as_src = src;
  68.     asacaCmd.as_dest = dest;
  69.     asacaCmd.as_mode = 0;
  70.     asacaCmd.as_barcode[0] = '\0';
  71.  
  72.     if (isvlds(src)) {
  73.     if (isvlds(dest)) {
  74.         cmdType = ASIOCMOVE1;
  75.     } else {
  76.         asacaCmd.as_src = dest; /* Don't ask me, ask Metrum */
  77.         asacaCmd.as_dest = src;
  78.         cmdType = ASIOCSTORE1;
  79.     }
  80.     } else {
  81.     if (isvlds(dest)) {
  82.         cmdType = ASIOCLOAD1;
  83.     } else {
  84.         cmdType = ASIOCMOVE2;
  85.     }
  86.     }
  87.     if (asaca_ioctl(robotStream, cmdType, &asacaCmd) != 0) {
  88.     syserr = errno;
  89.     return T_ROBOTFAILED;
  90.     } else {
  91.         return T_SUCCESS;
  92.     }
  93.  
  94. }
  95.  
  96.  
  97. /*
  98.  *----------------------------------------------------------------------
  99.  *
  100.  * Dev_OpenVolume --
  101.  *
  102.  *    Open the device
  103.  *
  104.  * Results:
  105.  *    return code
  106.  *
  107.  * Side effects:
  108.  *    None.
  109.  *
  110.  *----------------------------------------------------------------------
  111.  */
  112.  
  113. int
  114. Dev_OpenVolume(devName, flags)
  115.     char *devName;            /* name of device */
  116.     int flags;                /* read, write etc. flags */
  117. {
  118.     int fd;
  119.  
  120.     if ((fd=open(devName, flags, 0)) == -1) {
  121.     syserr = errno;
  122.     }
  123.     return fd;
  124. }
  125.  
  126.  
  127. /*
  128.  *----------------------------------------------------------------------
  129.  *
  130.  * Dev_CloseVolume --
  131.  *
  132.  *    Close the device
  133.  *
  134.  * Results:
  135.  *    return code
  136.  *
  137.  * Side effects:
  138.  *    None.
  139.  *
  140.  *----------------------------------------------------------------------
  141.  */
  142.  
  143. int
  144. Dev_CloseVolume(stream)
  145.     int stream;               /* file descriptor */
  146. {
  147.     if (close(stream) == -1) {
  148.     syserr = errno;
  149.     return T_FAILURE;
  150.     } else {
  151.     return T_SUCCESS;
  152.     }
  153. }
  154.  
  155.  
  156. /*
  157.  *----------------------------------------------------------------------
  158.  *
  159.  * Dev_ReadVolume --
  160.  *
  161.  *    Perform read operation on volume.
  162.  *
  163.  * Results:
  164.  *    return code
  165.  *
  166.  * Side effects:
  167.  *    None.
  168.  *
  169.  *----------------------------------------------------------------------
  170.  */
  171.  
  172. int
  173. Dev_ReadVolume(volStream, buf, bufSize)
  174.     int volStream;
  175.     char *buf;
  176.     int bufSize;
  177. {
  178.     int cnt;
  179.  
  180.     if ((cnt=read(volStream, buf, bufSize)) < 0) {
  181.     syserr = errno;
  182.     }
  183.     return cnt;
  184. }
  185.  
  186.  
  187. /*
  188.  *----------------------------------------------------------------------
  189.  *
  190.  * Dev_WriteVolume --
  191.  *
  192.  *    Perform write operation on volume.
  193.  *
  194.  * Results:
  195.  *    return code
  196.  *
  197.  * Side effects:
  198.  *    None.
  199.  *
  200.  *----------------------------------------------------------------------
  201.  */
  202.  
  203. int
  204. Dev_WriteVolume(volStream, buf, bufSize)
  205.     int volStream;
  206.     char *buf;
  207.     int bufSize;
  208. {
  209.     int cnt;
  210.  
  211.     if ((cnt=write(volStream, buf, bufSize)) < 0) {
  212.     syserr = errno;
  213.     }
  214.     return cnt;
  215. }
  216.  
  217.  
  218. /*
  219.  *----------------------------------------------------------------------
  220.  *
  221.  * Dev_UnloadVolume --
  222.  *
  223.  *    Open the pod bay door. I'm sorry I can't do that Dave.
  224.  *
  225.  * * Results:
  226.  *    return code
  227.  *
  228.  * Side effects:
  229.  *    Rewinds and unloads tape. Moves robot arm.
  230.  *
  231.  *----------------------------------------------------------------------
  232.  */
  233.  
  234. int
  235. Dev_UnloadVolume(devName)
  236.     char *devName;            /* device name */
  237. {
  238.     int volStream;
  239.     Dev_TapeCommand tapeCmd;
  240.  
  241.     if ((volStream=open(devName, O_RDONLY, 0)) < 0) {
  242.     syserr = errno;
  243.     return T_FAILURE;
  244.     }
  245.     
  246.     tapeCmd.mt_op = MTOFFL;
  247.     tapeCmd.mt_count = 1;
  248.  
  249.     if (ioctl(volStream, MTIOCTOP, (char *)&tapeCmd) != 0) {
  250.     syserr = errno;
  251.         close(volStream);
  252.     return T_FAILURE;
  253.     }
  254.     close(volStream);
  255.  
  256.     return T_SUCCESS;
  257.  
  258. }
  259.  
  260. /*
  261.  *----------------------------------------------------------------------
  262.  *
  263.  * Dev_InitRobot --
  264.  *
  265.  *    Initialize robot.
  266.  *
  267.  * Results:
  268.  *    return code
  269.  *
  270.  * Side effects:
  271.  *    Instructs robot to build database of volume id's
  272.  *      using barcode reader.
  273.  *
  274.  * Note:
  275.  *      No tape inventory at the moment.
  276.  *      
  277.  *----------------------------------------------------------------------
  278.  */
  279.  
  280. int
  281. Dev_InitRobot(robotName, robotStreamPtr)
  282.     char *robotName;          /* robot device name */
  283.     int *robotStreamPtr;      /* robot descriptor */
  284. {
  285.     if ((*robotStreamPtr=asaca_open(robotName)) == 0) {
  286.     syserr = errno;
  287.     return T_FAILURE;
  288.     } else {
  289.     return T_SUCCESS;
  290.     }
  291. }
  292.  
  293.  
  294. /*
  295.  *----------------------------------------------------------------------
  296.  *
  297.  * Dev_ReadVolLabel --
  298.  *
  299.  *    Read volume label with barcode reader
  300.  *
  301.  * Results:
  302.  *    return code
  303.  *
  304.  * Side effects:
  305.  *    Instructs robot to return element status from its database.
  306.  *
  307.  * Note:
  308.  *      Must adjust label conversion hack for local environment
  309.  *      
  310.  *----------------------------------------------------------------------
  311.  */
  312.  
  313. int
  314. Dev_ReadVolLabel(robotStream, location, volLabel, volIdPtr)
  315.     int robotStream;          /* robot descriptor */
  316.     int location;             /* home slot in jukebox */
  317.     char *volLabel;           /* receiving space for volume label */
  318.     int *volIdPtr;            /* receiving space for converted label */
  319. {
  320.     struct ascmd asacaCmd;
  321.  
  322.     asacaCmd.as_src = location;
  323.     asacaCmd.as_dest = 0;
  324.     asacaCmd.as_mode = 0;
  325.     asacaCmd.as_barcode[0] = '\0';
  326.  
  327.     if (asaca_ioctl(robotStream, ASIOCBCREAD2, &asacaCmd) != 0) {
  328.     syserr = errno;
  329.     return T_ROBOTFAILED;
  330.     } else {
  331.     strcpy(volLabel, asacaCmd.as_barcode);
  332.     *volIdPtr = Dev_CvtVolLabel(volLabel);
  333.         return T_SUCCESS;
  334.     }
  335.  
  336. }
  337.  
  338.  
  339. /*
  340.  *----------------------------------------------------------------------
  341.  *
  342.  * Dev_CvtVolLabel --
  343.  *
  344.  *    Convert character volume label to unique integer.
  345.  *
  346.  * Results:
  347.  *    return code
  348.  *
  349.  * Side effects:
  350.  *    None.
  351.  *
  352.  * Note:
  353.  *      For present purposes, labels are of the form "<text><number>"
  354.  *
  355.  *----------------------------------------------------------------------
  356.  */
  357.  
  358. int
  359. Dev_CvtVolLabel(volLabel)
  360.     char *volLabel;
  361. {
  362.     int volId;
  363.     char *workPtr = volLabel+strlen(volLabel)-1;
  364.  
  365.     while ((workPtr >= volLabel) && (isdigit(*workPtr))) {
  366.     workPtr--;
  367.     }
  368.     if ((workPtr >= volLabel) && (sscanf(workPtr+1, "%d", &volId) == 1)) {
  369.     return volId;
  370.     } else {
  371.     return -1;
  372.     }
  373. }
  374.  
  375.  
  376. /*
  377.  *----------------------------------------------------------------------
  378.  *
  379.  * Dev_SeekVolume --
  380.  *
  381.  *    Seek to file marker
  382.  *
  383.  * Results:
  384.  *    return code
  385.  *
  386.  * Side effects:
  387.  *    Instructs tape to seek
  388.  *
  389.  *----------------------------------------------------------------------
  390.  */
  391.  
  392. int
  393. Dev_SeekVolume(volStream, blkId, absolute)
  394.     int volStream;            /* volume descriptor */
  395.     int blkId;                /* logical file num */
  396.     int absolute;             /* absolute positioning flag */
  397. {
  398.     int status;
  399.     Dev_TapeCommand tapeCmd;
  400.     int oldOffset = 0;
  401.     int retryCnt = 0;
  402.  
  403.     if ((blkId < 0) || (blkId > 10000)) {
  404.     fprintf(stderr,"Dev_SeekVolume: Bad blkId: %d\n", blkId);
  405.     }
  406.  
  407.     if ((volStream < 0) || (volStream > 20)) {
  408.     fprintf(stderr,"Dev_SeekVolume: Bad volStream: %d\n", volStream);
  409.     }
  410.  
  411.     if (absolute) {
  412.     tapeCmd.mt_op = MTREW;
  413.     tapeCmd.mt_count = 1;
  414.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  415.     while ((retryCnt++ < 5) && (status != 0)) {
  416.         fprintf(stderr, "Rewind failed: errno %d. Retrying...\n",
  417.             errno);
  418.         sleep(2);
  419.         status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  420.     }
  421.     if (status != 0) {
  422.         syserr = errno;
  423.         fprintf(stderr, "Couldn't rewind tape. errno %d\n",syserr);
  424.         return T_IOFAILED;
  425.     }
  426.     }
  427.  
  428.     if (blkId > 0) {
  429.     tapeCmd.mt_op = MTFSF;
  430.     tapeCmd.mt_count = blkId;
  431.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  432.     if (status != 0) {
  433.         syserr = errno;
  434.         fprintf(stderr, "Couldn't skip %d files: %d\n",
  435.             blkId, syserr);
  436.         return T_IOFAILED;
  437.     }
  438.     }
  439.  
  440.     return T_SUCCESS;
  441. }
  442.  
  443.  
  444.  
  445. /*
  446.  *----------------------------------------------------------------------
  447.  *
  448.  * Dev_WriteEOF --
  449.  *
  450.  *    write out EOF
  451.  *
  452.  * Results:
  453.  *    return code
  454.  *
  455.  * Side effects:
  456.  *    Puts file marker on tape
  457.  *
  458.  *----------------------------------------------------------------------
  459.  */
  460.  
  461. int
  462. Dev_WriteEOF(volStream, count)
  463.     int volStream;            /* active stream */
  464.     int count;                /* number of marks to write */
  465. {
  466.     int status;
  467.     Dev_TapeCommand tapeCmd;
  468.  
  469.     tapeCmd.mt_op = MTWEOF;
  470.     tapeCmd.mt_count = count;
  471.  
  472.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  473.  
  474.     if (status == 0) {
  475.     return T_SUCCESS;
  476.     } else {
  477.     syserr = errno;
  478.     return T_IOFAILED;
  479.     }
  480. }
  481.  
  482.  
  483.  
  484. /*
  485.  *----------------------------------------------------------------------
  486.  *
  487.  * Dev_GetVolStatus --
  488.  *
  489.  *    Inquire into state of volume device
  490.  *
  491.  * Results:
  492.  *    return code
  493.  *
  494.  * Side effects:
  495.  *    None.
  496.  *
  497.  *----------------------------------------------------------------------
  498.  */
  499.  
  500. int
  501. Dev_GetVolStatus(volStream, volStatusPtr)
  502.     int volStream;            /* volume descriptor */
  503.     VolStatus *volStatusPtr;  /* receiving structure */
  504. {
  505.  
  506.     volStatusPtr->position = -1;
  507.     return T_SUCCESS;
  508. }
  509.  
  510. /*
  511.  *----------------------------------------------------------------------
  512.  *
  513.  * Dev_DisplayMsg --
  514.  *
  515.  *    Display message on jukebox screen
  516.  *
  517.  * Results:
  518.  *    return code
  519.  *
  520.  * Side effects:
  521.  *    None.
  522.  *
  523.  *----------------------------------------------------------------------
  524.  */
  525.  
  526. int
  527. Dev_DisplayMsg(robotStream, msg, msgStyle)
  528.     int robotStream;          /* volume descriptor */
  529.     char *msg;                /* Message text */
  530.     int msgStyle;             /* 0==Steady, 1==flash, 2==scroll */
  531. {
  532.  
  533.     return T_SUCCESS;
  534.  
  535. }
  536.  
  537. /*
  538.  *----------------------------------------------------------------------
  539.  *
  540.  * Dev_OpenDoor --
  541.  *
  542.  *    Open (or at least unlock) the jukebox door.
  543.  *
  544.  * Results:
  545.  *    return code
  546.  *
  547.  * Side effects:
  548.  *    None.
  549.  *
  550.  *----------------------------------------------------------------------
  551.  */
  552.  
  553. int
  554. Dev_OpenDoor(robotStream)
  555.     int robotStream;          /* robot descriptor */
  556. {
  557.     struct ascmd asacaCmd;
  558.  
  559.     asacaCmd.as_src = 0;
  560.     asacaCmd.as_dest = 0;
  561.     asacaCmd.as_mode = 0;
  562.     asacaCmd.as_barcode[0] = '\0';
  563.  
  564.     if (asaca_ioctl(robotStream, ASIOCDOOROPEN, &asacaCmd) != 0) {
  565.     syserr = errno;
  566.     return T_ROBOTFAILED;
  567.     } else {
  568.         return T_SUCCESS;
  569.     }
  570. }
  571.  
  572.  
  573. /*
  574.  *----------------------------------------------------------------------
  575.  *
  576.  * Dev_RemoveVolume --
  577.  *
  578.  *    Open (or at least unlock) the jukebox door.
  579.  *
  580.  * Results:
  581.  *    return code
  582.  *
  583.  * Side effects:
  584.  *    Kicks a volume out of archive.
  585.  *
  586.  *----------------------------------------------------------------------
  587.  */
  588.  
  589. int
  590. Dev_RemoveVolume(robotStream, src)
  591.     int robotStream;          /* robot descriptor */
  592.     int src;                  /* src slot location */
  593.     /* the best we can do on a metrum is open the door. */
  594.     return Dev_OpenDoor(robotStream);
  595.  
  596. }
  597.  
  598.  
  599. /*
  600.  *----------------------------------------------------------------------
  601.  *
  602.  * Dev_InsertVolume --
  603.  *
  604.  *    Open (or at least unlock) the jukebox door.
  605.  *
  606.  * Results:
  607.  *    return code
  608.  *
  609.  * Side effects:
  610.  *    Pull in a new volume.
  611.  *
  612.  *----------------------------------------------------------------------
  613.  */
  614.  
  615. int
  616. Dev_InsertVolume(robotStream, dest)
  617.     int robotStream;          /* robot descriptor */
  618.     int dest;                 /* destination slot location */
  619.     /* the best we can do on a metrum is open the door. */
  620.     return Dev_OpenDoor(robotStream);
  621.  
  622. }
  623.  
  624.  
  625. /*
  626.  *----------------------------------------------------------------------
  627.  *
  628.  * Dev_BuildVolList --
  629.  *
  630.  *    Build a list of jukebox's contents
  631.  *
  632.  * Results:
  633.  *    return code
  634.  *
  635.  * Side effects:
  636.  *    none.
  637.  *
  638.  *----------------------------------------------------------------------
  639.  */
  640.  
  641. int
  642. Dev_BuildVolList(robotStream, listPtr, cntPtr)
  643.     int robotStream;          /* robot descriptor */
  644.     VolConfig *listPtr;       /* space for volume info */
  645.     int *cntPtr;              /* size of list */
  646.                 
  647.     int i;
  648.     int cnt = 0;
  649.     int maxBin = AS_MAXBIN+1;
  650.     int retCode = T_SUCCESS;
  651.     char label[T_MAXLABELLEN];
  652.     
  653.     if (*cntPtr < maxBin) {
  654.     syserr = ENOSPC;
  655.     *cntPtr = AS_MAXBIN+1;
  656.     return T_FAILURE;
  657.     }
  658.  
  659.     for (i=0; i<maxBin; i++) {
  660.     if ((retCode=Dev_ReadVolLabel(robotStream, i, label)) != T_SUCCESS) {
  661.         *cntPtr = 0;
  662.         return retCode;
  663.     }
  664.     if (strcmp(label, "*************") != 0) {
  665.         listPtr->volId = i;
  666.         listPtr->location = i;
  667.         strcpy(listPtr->volLabel, label);
  668.         listPtr++;
  669.         cnt++;
  670.     }
  671.     }
  672.  
  673.     *cntPtr = cnt;
  674.     return T_SUCCESS;
  675.  
  676. }
  677.